package com.mingyuan.library.domain.lending.patron.model.valueobject;

import com.mingyuan.library.domain.common.model.ValueObject;
import lombok.NonNull;
import lombok.Value;

import java.time.Duration;
import java.time.Instant;

import static java.time.Instant.now;

/**
 * 借阅持续时间
 */
@Value
@ValueObject
public class CheckoutDuration {

    static final int MAX_CHECKOUT_DURATION = 60;
    /**
     * 借阅多少天
     */
    @NonNull NumberOfDays noOfDays;
    /**
     * 从那天开始
     */
    @NonNull Instant from;

    /**
     * 创建借阅周期手机里
     *
     * @param from     借阅开始时间
     * @param noOfDays 借阅时长(天)
     * @author yangzk
     * @date 2023/12/28 18:29
     **/
    private CheckoutDuration(Instant from, NumberOfDays noOfDays) {
        // 校验借阅时长是否大于最大借阅时长
        if (noOfDays.isGreaterThan(MAX_CHECKOUT_DURATION)) {
            throw new IllegalArgumentException("Cannot checkout for more than " + MAX_CHECKOUT_DURATION + " days!");
        }
        this.noOfDays = noOfDays;
        this.from = from;
    }

    /**
     * 创建借阅周期
     *
     * @param noOfDays 借阅时长(天)/借阅总天数
     * @return 借阅持续时间信息
     * @author yangzk
     * @date 2023/12/28 18:20
     **/
    public static CheckoutDuration forNoOfDays(int noOfDays) {
        return forNoOfDays(now(), noOfDays);
    }

    /**
     * 从什么时间借阅到那天
     *
     * @param from     借阅开始时间
     * @param noOfDays 借阅时长
     * @return 借阅持续时间信息
     * @author yangzk
     * @date 2023/12/28 18:26
     **/
    static CheckoutDuration forNoOfDays(Instant from, int noOfDays) {
        return new CheckoutDuration(from, NumberOfDays.of(noOfDays));
    }

    /**
     * 借阅上限时间
     *
     * @author yangzk
     * @date 2023/12/28 18:46
     **/
    public static CheckoutDuration maxDuration() {
        return forNoOfDays(MAX_CHECKOUT_DURATION);
    }

    /**
     * 借阅截止时间
     *
     * @author yangzk
     * @date 2023/12/28 18:44
     **/
    public Instant to() {
        return from.plus(Duration.ofDays(noOfDays.getDays()));
    }
}
